use crate::error::with_context;
use crate::file_system::write_to_file;
use crate::model::CodeModule;
use crate::model::{EntryInfo, NpmModuleInfo, ProjectDirInfo, VueBlock};
use crate::traits::CommonModuleTrait;
use crate::util::resolve_path;
use std::fs;

pub fn init_import(
    project_dir_info: &ProjectDirInfo,
    npm_module_info: &NpmModuleInfo,
) -> Result<(), Box<dyn std::error::Error>> {
    // 在app.vue中写入信息
    if npm_module_info.package_json.exists() {
        if let Some(entry_info) = npm_module_info.try_get_entry_info() {
            apply_entry(project_dir_info, &entry_info)?;
        }
    }
    Ok(())
}

fn apply_entry(
    project_dir_info: &ProjectDirInfo,
    entry_info: &EntryInfo,
) -> Result<(), Box<dyn std::error::Error>> {
    let vue_block = VueBlock::new(&fs::read_to_string(project_dir_info.app_vue()).map_err(
        |err| {
            with_context(
                err,
                &format!(
                    "无效app.vue路径:{:?}",
                    resolve_path(project_dir_info.app_vue())
                ),
            )
        },
    )?);

    if let Some(source_code) = vue_block.try_get_script_block() {
        let mut code_module = CodeModule::new(&source_code)?;
        code_module.init_import(&entry_info.into())?;

        write_to_file(
            project_dir_info.app_vue(),
            vue_block
                .update_script_block(&code_module.get_source())?
                .get_source(),
        )?;
    }
    Ok(())
}
